Extracting from the archive

back to section start!

 
  The user has copied something out of the lister, or dragged something from 
the lister and dropped it on another one.  Either way we need to extract it. 
 
  1arcextract: 
  2  lister set handle busy on 
  3  if otherhandle = 0 then 
  4    if newopus then 
  5      winpath = deststr 
  6    else do 
  7      call displayerror(getcatstr(9,'No destination selected!')) 
  8      return 
  9      end 
 10  else do 
 11    if checkhandler() then 
 12      return 
 13    lister set otherhandle busy on 
 14    lister query otherhandle path 
 15    winpath = result 
 16    end 
 17 
 18  lister query handle numdirs 
 19  anydirs = result > 0 
 20  mustmove = anydirs & arcsubdir ~== '' 
 21  if mustmove then do 
 22    destpath = winpath'ArcDir'handle 
 23    call makedir(destpath) 
 24    destpath = destpath'/' 
 25    end 
 26  else 
 27    destpath = winpath 
 28 
 29  lister set handle title getcatstr(10,'Extracting from archive...') 
 30  lister refresh handle full 
 31 
 32  select 
 33    when arctype = 'LHA' then do 
 34      call open('actionfile','T:actionfile'handle,'w') 
 35      do i = 1 to entries 
 36        if type.i > 0 then 
 37          wild = '/#?' 
 38        else 
 39          wild = '' 
 40        call writeln('actionfile','"'patch(arcsubdir||name.i,1)||wild'"') 
 41        end 
 42      call close('actionfile') 
 43 
 44      if anydirs then 
 45        cmd = 'x' 
 46      else 
 47        cmd = 'e -x2' 
 48      address command 'LhA' cmd '-q -a -C0 -X -Qo "'patch(arcfile,0)'" "'destpath'" @T:actionfile'handle 
 49      problem = rc > 0 
 50      call delete('T:actionfile'handle) 
 51      end 
 52    when arctype = 'LZX' then do 
 53      if anydirs then 
 54        cmd = 'x' 
 55      else 
 56        cmd = 'e' 
 57      lzxcmd = 'LZX' cmd '-q -a -C0 -X0 --' lzxkludge(patch(arcfile,0)) 
 58 
 59      linelen = 0 
 60      n = 0 
 61      do i = 1 to entries 
 62        if type.i > 0 then 
 63          wild = '/#?' 
 64        else 
 65          wild = '' 
 66        dothis = lzxkludge(patch(arcsubdir||name.i,0)||wild) 
 67        linelen = linelen + length(dothis) + 1 
 68        if i = 1 | linelen > 255 then do 
 69          n = n + 1 
 70          dothese.n = dothis 
 71          linelen = length(lzxcmd) + length(dothis) + 1 
 72          end 
 73        else 
 74          dothese.n = dothese.n dothis 
 75        end 
 76 
 77      oldcurrent = pragma('d') 
 78      call pragma('d',destpath) 
 79      do i = 1 to n 
 80        address command lzxcmd dothese.i 
 81        problem = rc > 0 
 82        if problem > 0 then 
 83          leave 
 84        end 
 85      call pragma('d',oldcurrent) 
 86      end 
 87    end 
 88 
 89  if problem then 
 90    call displayerror(getcatstr(11,'Error while extracting from archive.')) 
 91  else 
 92    do i = 1 to entries 
 93      lister select handle '"'name.i'"' off 
 94      end 
 95 
 96  lister set handle title 'ArcDir:' arcname 
 97  lister refresh handle full 
 98 
 99  if mustmove then do 
100    address command 'DOpus5:C/Move >NIL: "'destpath||arcsubdir'#?" "'winpath'"' 
101    address command 'Delete >NIL: "'winpath'ArcDir'handle'" ALL QUIET' 
102    end 
103 
104  if otherhandle ~= 0 then do 
105    lister set otherhandle busy off 
106    lister read otherhandle '"'winpath'"' force 
107    end 
108  return 
 
Line: 
 1      Sub-routine label. 
 2      Change the ArcDir lister to state busy. 
 3      If the handle given to us for the other lister equals 0 then... 
 4 - 5  If it's an Opus version later than 5.1215, (newopus was set back 
         here ), then we set winpath to the string returned in argument 
        7 of the message packet. 
 6 - 9  If it's an earlier version of Opus, then we display an error message 
        and return immediately, (upgrade :) 
10 - 16 If the handle didn't equal 0 then we check to see if the other lister 
        is a custom handler, if it is then we return immediately.  If it 
        isn't we set the state of the other lister to busy and get it's path 
        in winpath. 
18 - 19 We see if there are any directories in our ArcDir lister display, if 
        there are we set anydirs to 1. 
20      We set mustmove to 1 if anydirs was set to 1 and we are not in the 
        root directory of the archive. 
21 - 25 If mustmove is true (1), then we will have to extract to a directory 
        structure in T:, so we call the  makedir  routine to create it and 
        set destpath to the created directory. 
26 - 27 Otherwise we set destpath to equal winpath. 
29 - 30 Set the ArcDir lister titlebar to tell the user what we're doing and 
        refresh the display. 
32 - 87 Now depending what type of archive it is, we do the appropriate part 
        of the Select...When conditional block, I'll assume LhA because it's 
        easier :) 
34      We open a file in T: for writing to, it will contain the entries that 
        we want to extract. 
35 - 41 A DO loop in which we check the TYPE of the entry, (as detected in 
        the  getall  routine), if it's a directory we set wild to '#?', 
        if not then we set it to an empty string.  We then write the entry to 
        the temporary file in T:,  patching  the string for strange 
        characters and adding wild.  Keep doing it until there are no more 
        entries to add. 
42      Close the temporary file. 
44 - 47 If anydirs was set to true (1), then we make the extraction method 
        'x' (full paths) otherwise we set it to 'e -x2' (ignore paths), see 
        the LhA docs. 
48      Run the archiver with the name of our archive,  patching  for any 
        strange characters, and the list of files to extract. 
49      If there was a problem set problem to true (1). 
50      Delete the temporary file in T:. 
51      End of the When block for LhA archives. 
89 - 90 If there was a problem extracting entries, tell the user via the 
         displayerror  routine, translating if necessary through the 
         getcatstr  routine. 
91 - 97 If there wasn't any problem then we unselect all our selected 
        entries, set the ArcDir titlebar back to it's normal display and do a 
        full refresh to update the lister display. 
99 -102 If mustmove was true, then we need to move the extracted entries from 
        the directory structure in T: to the destination path, destpath. 
        Then we delete the directory structure in T:. 
104-107 If otherhandle doesn't equal 0, then there is a destination lister, 
        we set it's state back to idle and force it to reread the directory. 
108     We return. 
 

DOpus PLUS - giving you that bit extra...